# -*- coding: utf-8 -*-
"""
插件管理器
用于管理和初始化所有插件下的Python文件
参照ThemeManager.py的结构，但使用plugin_manager.py中的蓝图注册方式
"""
import os
import datetime
import sys
import importlib.util
import shutil
import zipfile
import tempfile
import json
import logging
from apps.common.utils.route_manager import (
    route_enable_plugin,
    route_disable_plugin
)
from werkzeug.utils import secure_filename
from typing import Dict, List, Any, Optional
from flask import Flask, Blueprint

logger = logging.getLogger(__name__)


class PluginManager:
    """插件管理器类"""
    
    def __init__(self, app=None):
        self.app = app
        self.plugins = {}
        self.plugins_info = {}
        self.initialized_modules = {}
        self.plugin_dir = None
        
    def set_app(self, app):
        """设置Flask应用实例"""
        self.app = app
        
    def get_plugin_dir(self) -> str:
        """获取插件目录的绝对路径"""
        if self.plugin_dir is None:
            if self.app:
                self.plugin_dir = os.path.join(self.app.root_path, '..', 'plugins')
            else:
                # 如果没有app实例，使用相对路径
                project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
                self.plugin_dir = os.path.join(project_root, 'plugins')
            
            # 确保插件目录存在
            os.makedirs(self.plugin_dir, exist_ok=True)
            
        return self.plugin_dir
        
    def discover_plugins(self) -> Dict[str, str]:
        """发现所有插件目录"""
        plugin_dir = self.get_plugin_dir()
        
        if not os.path.exists(plugin_dir):
            print(f"❌ 插件目录不存在: {plugin_dir}")
            return {}
            
        plugins = {}
        for item in os.listdir(plugin_dir):
            item_path = os.path.join(plugin_dir, item)
            if os.path.isdir(item_path):
                # 检查是否是有效的插件（包含plugin.json）
                config_file = os.path.join(item_path, 'plugin.json')
                if os.path.exists(config_file):
                    plugins[item] = item_path
                    print(f"🔍 发现插件: {item}")
                    
        return plugins
    
    def load_existing_plugins_info(self):
        """加载现有的插件信息"""
        plugin_dir = self.get_plugin_dir()
        plugins_json_file = os.path.join(plugin_dir, 'plugins.json')
        
        if os.path.exists(plugins_json_file):
            try:
                with open(plugins_json_file, 'r', encoding='utf-8') as f:
                    self.plugins_info = json.load(f)
                print(f"✅ 已加载 {len(self.plugins_info)} 个插件的配置信息")
            except Exception as e:
                print(f"❌ 加载插件配置信息失败: {e}")
                self.plugins_info = {}
        else:
            print("ℹ️ 插件配置文件不存在，将创建新的配置")
            self.plugins_info = {}
    
    def save_plugins_info(self):
        """保存插件信息到文件"""
        plugin_dir = self.get_plugin_dir()
        plugins_json_file = os.path.join(plugin_dir, 'plugins.json')
        
        try:
            with open(plugins_json_file, 'w', encoding='utf-8') as f:
                json.dump(self.plugins_info, f, ensure_ascii=False, indent=2)
            print(f"✅ 已保存 {len(self.plugins_info)} 个插件的配置信息")
        except Exception as e:
            print(f"❌ 保存插件配置信息失败: {e}")
        
    def load_python_file(self, file_path: str, module_name: str) -> Optional[Any]:
        """动态加载Python文件"""
        try:
            if not os.path.exists(file_path):
                return None
                
            spec = importlib.util.spec_from_file_location(module_name, file_path)
            module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(module)
            return module
            
        except Exception as e:
            print(f"❌ 加载模块 {module_name} 失败: {e}")
            return None
            
    def load_plugin_config(self, plugin_name: str, plugin_path: str) -> Optional[Dict]:
        """加载插件配置"""
        config_file = os.path.join(plugin_path, 'plugin.json')
        
        if not os.path.exists(config_file):
            print(f"❌ 插件 {plugin_name} 缺少配置文件: plugin.json")
            return None
            
        try:
            with open(config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
                
            # 验证必需字段
            required_fields = ['name', 'version', 'description', 'author']
            for field in required_fields:
                if field not in config:
                    print(f"❌ 插件 {plugin_name} 配置缺少必需字段: {field}")
                    return None
                    
            return config
            
        except Exception as e:
            print(f"❌ 加载插件 {plugin_name} 配置失败: {e}")
            return None
            
    def init_plugin_config(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化插件的config.py文件"""
        config_file = os.path.join(plugin_path, 'config.py')
        
        if not os.path.exists(config_file):
            print(f"ℹ️ {plugin_name} 插件下没有config.py文件")
            return False
            
        try:
            print(f"🔍 发现config.py在: {plugin_name}")
            
            module_name = f"config_{plugin_name}"
            config_module = self.load_python_file(config_file, module_name)
            
            if config_module is None:
                return False
                
            if hasattr(config_module, 'init'):
                if self.app:
                    config_module.init(self.app)
                else:
                    config_module.init()
                print(f"✅ {plugin_name} 插件config模块初始化成功")
                
            self.initialized_modules[f"{plugin_name}_config"] = config_module
            return True
            
        except Exception as e:
            print(f"❌ 初始化 {plugin_name} 插件config模块时发生错误: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def init_plugin_functions(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化插件的functions.py文件"""
        functions_file = os.path.join(plugin_path, 'functions.py')
        
        if not os.path.exists(functions_file):
            print(f"ℹ️ {plugin_name} 插件下没有functions.py文件")
            return False
            
        try:
            print(f"🔍 发现functions.py在: {plugin_name}")
            
            module_name = f"functions_{plugin_name}"
            functions_module = self.load_python_file(functions_file, module_name)
            
            if functions_module is None:
                return False
                
            if hasattr(functions_module, 'init'):
                if self.app:
                    functions_module.init(self.app)
                else:
                    functions_module.init()
                print(f"✅ {plugin_name} 插件functions模块初始化成功")
                
            self.initialized_modules[f"{plugin_name}_functions"] = functions_module
            return True
            
        except Exception as e:
            print(f"❌ 初始化 {plugin_name} 插件functions模块时发生错误: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def init_plugin_helpers(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化插件的helpers.py文件"""
        helpers_file = os.path.join(plugin_path, 'helpers.py')
        
        if not os.path.exists(helpers_file):
            print(f"ℹ️ {plugin_name} 插件下没有helpers.py文件")
            return False
            
        try:
            print(f"🔍 发现helpers.py在: {plugin_name}")
            
            module_name = f"helpers_{plugin_name}"
            helpers_module = self.load_python_file(helpers_file, module_name)
            
            if helpers_module is None:
                return False
                
            if hasattr(helpers_module, 'init'):
                if self.app:
                    helpers_module.init(self.app)
                else:
                    helpers_module.init()
                print(f"✅ {plugin_name} 插件helpers模块初始化成功")
                
            self.initialized_modules[f"{plugin_name}_helpers"] = helpers_module
            return True
            
        except Exception as e:
            print(f"❌ 初始化 {plugin_name} 插件helpers模块时发生错误: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def init_plugin_utils(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化插件的utils.py文件"""
        utils_file = os.path.join(plugin_path, 'utils.py')
        
        if not os.path.exists(utils_file):
            print(f"ℹ️ {plugin_name} 插件下没有utils.py文件")
            return False
            
        try:
            print(f"🔍 发现utils.py在: {plugin_name}")
            
            module_name = f"utils_{plugin_name}"
            utils_module = self.load_python_file(utils_file, module_name)
            
            if utils_module is None:
                return False
                
            if hasattr(utils_module, 'init'):
                if self.app:
                    utils_module.init(self.app)
                else:
                    utils_module.init()
                print(f"✅ {plugin_name} 插件utils模块初始化成功")
                
            self.initialized_modules[f"{plugin_name}_utils"] = utils_module
            return True
            
        except Exception as e:
            print(f"❌ 初始化 {plugin_name} 插件utils模块时发生错误: {e}")
            import traceback
            traceback.print_exc()
            return False

    def init_plugin_models(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化插件的models.py文件"""
        utils_file = os.path.join(plugin_path, 'models.py')

        if not os.path.exists(utils_file):
            print(f"ℹ️ {plugin_name} 插件下没有models.py文件")
            return False

        try:
            print(f"🔍 发现models.py在: {plugin_name}")

            module_name = f"models_{plugin_name}"
            models_module = self.load_python_file(utils_file, module_name)

            if models_module is None:
                return False

            if hasattr(models_module, 'init'):
                if self.app:
                    models_module.init(self.app)
                else:
                    models_module.init()
                print(f"✅ {plugin_name} 插件models模块初始化成功")

            self.initialized_modules[f"{plugin_name}_models"] = models_module
            return True

        except Exception as e:
            print(f"❌ 初始化 {plugin_name} 插件models模块时发生错误: {e}")
            import traceback
            traceback.print_exc()
            return False

    def init_plugin_view(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化插件的view.py文件（蓝图）"""
        view_file = os.path.join(plugin_path)
        
        if not os.path.exists(view_file):
            print(f"ℹ️ {plugin_name} 插件下没有view.py文件")
            return False
            
        try:
            print(f"🔍 发现view.py在: {plugin_name}")
            
            # 动态加载view模块
            module_name = f"view_{plugin_name}"
            sys.path.insert(0, self.plugin_dir)
            try:
                view_module = importlib.import_module(f'{plugin_name}.view')
                # 查找蓝图实例
                blueprint = None
                for attr_name in dir(view_module):
                    attr = getattr(view_module, attr_name)
                    if isinstance(attr, Blueprint):
                        blueprint = attr
                        break

                if blueprint:
                    # 注册蓝图
                    try:
                        # 检查蓝图是否已经注册
                        if blueprint.name not in self.app.blueprints:
                            # 检查应用是否已经处理过请求
                            if hasattr(self.app, '_got_first_request') and self.app._got_first_request:
                                print(f"⚠️ Flask应用已处理过请求，无法注册蓝图 {blueprint.name}")
                                print(f"ℹ️ 蓝图 {blueprint.name} 将在下次应用重启时自动注册")
                                # 将蓝图存储在待注册列表中，供后续使用
                                if not hasattr(self, '_pending_blueprints'):
                                    self._pending_blueprints = {}
                                self._pending_blueprints[blueprint.name] = blueprint
                                self._create_reload_config()
                            else:
                                self.app.register_blueprint(blueprint)
                                self.initialized_modules[f"{plugin_name}_view"] = view_module
                                print(f"✅ {plugin_name} 插件蓝图注册成功: {blueprint.name}")
                        else:
                            print(f"ℹ️ {plugin_name} 插件蓝图已存在: {blueprint.name}")
                    except Exception as e:
                        print(f"❌ 注册 {plugin_name} 插件蓝图失败: {e}")
                        # 如果是运行时注册失败，将蓝图存储在待注册列表中
                        if not hasattr(self, '_pending_blueprints'):
                            self._pending_blueprints = {}
                        self._pending_blueprints[blueprint.name] = blueprint
                        print(f"ℹ️ 蓝图 {blueprint.name} 已添加到待注册列表")
                else:
                    logger.error(f"✗ 插件 {plugin_name} 中未找到蓝图")
                    return False
            except Exception as e:
                logger.error(f"✗ 注册插件 {plugin_name} 失败: {e}")
                return False
            print(f"✅ {plugin_name} 插件view模块蓝图加载成功")
            return True
            
        except Exception as e:
            print(f"❌ 初始化 {plugin_name} 插件view模块时发生错误: {e}")
            import traceback
            traceback.print_exc()
            return False

    def _create_reload_config(self):
        """
        创建重载配置文件
        """
        try:
            import os
            import json
            import time

            print("🔄 检测到待插件注册的蓝图，创建重载配置文件...")

            # 获取待注册的蓝图信息
            pending_blueprints = getattr(self, '_pending_blueprints', {})
            pending_info = {}

            # 保存蓝图详细信息
            for name, blueprint in pending_blueprints.items():
                pending_info[name] = {
                    'name': blueprint.name,
                    'url_prefix': blueprint.url_prefix,
                    'template_folder': blueprint.template_folder,
                    'static_folder': getattr(blueprint, 'static_folder', None),
                    'static_url_path': getattr(blueprint, 'static_url_path', None)
                }

            # 创建重载配置文件
            reload_config = {
                'timestamp': time.time(),
                'pending_blueprints': list(pending_blueprints.keys()),
                'pending_blueprint_info': pending_info,
                'action': 'reload_app',
                'reason': 'pending_blueprints_detected'
            }

            # 获取项目根目录
            project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
            reload_file = os.path.join(project_root, 'reload_app.json')

            # 写入重载配置
            with open(reload_file, 'w', encoding='utf-8') as f:
                json.dump(reload_config, f, indent=2, ensure_ascii=False)

            print(f"✅ 重载配置文件已创建: {reload_file}")
            print("ℹ️ 请使用 auto_reload_monitor.py 监控此文件以自动重启应用")

        except Exception as e:
            print(f"❌ 创建重载配置文件失败: {e}")
            
    def _register_blueprint_manual(self, blueprint: Blueprint, plugin_name: str, config: Dict) -> bool:
        """手动注册蓝图（应用已初始化时）"""
        try:
            # 检查是否有Flask应用实例
            if not self.app:
                print(f"⚠️ 没有Flask应用实例，跳过手动注册")
                return False
                
            blueprint_name = blueprint.name
            url_prefix = blueprint.url_prefix or config.get('url_prefix', f'/{plugin_name}')
            
            print(f"手动注册蓝图: {blueprint_name}, URL前缀: {url_prefix}")
            
            # 尝试直接注册
            try:
                self.app.register_blueprint(blueprint)
                print(f"✓ 蓝图 {blueprint_name} 直接注册成功")
                return True
            except Exception as e:
                print(f"直接注册失败: {e}")
                
            # 手动注册方法
            for endpoint, view_func in blueprint.view_functions.items():
                full_endpoint = f"{blueprint_name}.{endpoint}"
                self.app.view_functions[full_endpoint] = view_func
                
            print(f"✓ 蓝图 {blueprint_name} 手动注册成功")
            return True
            
        except Exception as e:
            print(f"手动注册蓝图失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def init_plugin(self, plugin_name: str, plugin_path: str) -> bool:
        """初始化单个插件的所有模块"""
        print(f"\n🚀 开始初始化插件: {plugin_name}")
        
        # 加载插件配置
        config = self.load_plugin_config(plugin_name, plugin_path)
        if not config:
            return False
        
        # 将插件配置保存到 self.plugins_info
        if plugin_name not in self.plugins_info:
            # 新插件，创建完整配置
            self.plugins_info[plugin_name] = {
                'name': config.get('name', plugin_name),
                'version': config.get('version', '1.0.0'),
                'description': config.get('description', ''),
                'author': config.get('author', ''),
                'blueprint_name': config.get('blueprint_name', ''),
                'url_prefix': config.get('url_prefix', f'/{plugin_name}'),
                'modules': config.get('modules', []),
                'enabled': True,  # 默认启用
                'installed_at': str(datetime.datetime.now())
            }
        else:
            # 现有插件，更新配置信息
            existing_info = self.plugins_info[plugin_name]
            existing_info.update({
                'name': config.get('name', existing_info.get('name', plugin_name)),
                'version': config.get('version', existing_info.get('version', '1.0.0')),
                'description': config.get('description', existing_info.get('description', '')),
                'author': config.get('author', existing_info.get('author', '')),
                'blueprint_name': config.get('blueprint_name', existing_info.get('blueprint_name', '')),
                'url_prefix': config.get('url_prefix', existing_info.get('url_prefix', f'/{plugin_name}')),
                'modules': config.get('modules', existing_info.get('modules', [])),
                'enabled': existing_info.get('enabled', True)  # 保持现有启用状态
            })
            
        success_count = 0
        total_count = 0
        
        # 初始化config.py
        if self.init_plugin_config(plugin_name, plugin_path):
            success_count += 1
        total_count += 1
        
        # 初始化functions.py
        if self.init_plugin_functions(plugin_name, plugin_path):
            success_count += 1
        total_count += 1
        
        # 初始化helpers.py
        if self.init_plugin_helpers(plugin_name, plugin_path):
            success_count += 1
        total_count += 1
        
        # 初始化utils.py
        if self.init_plugin_utils(plugin_name, plugin_path):
            success_count += 1
        total_count += 1
        # 初始化utils.py
        if self.init_plugin_models(plugin_name, plugin_path):
            success_count += 1
        total_count += 1
        # 初始化view.py（优先）
        if self.init_plugin_view(plugin_name, plugin_path):
            success_count += 1
            total_count += 1
        else:
            # 如果没有view.py，尝试初始化蓝图文件
            if self.init_plugin_blueprint(plugin_name, plugin_path, config):
                success_count += 1
            total_count += 1
        
        print(f"📊 {plugin_name} 插件初始化完成: {success_count}/{total_count} 个模块成功")
        return success_count > 0
        
    def init_plugin_blueprint(self, plugin_name: str, plugin_path: str, config: Dict) -> bool:
        """初始化插件的蓝图（兼容旧版本）"""
        blueprint_name = config.get('blueprint_name')
        if not blueprint_name:
            print(f"❌ 插件 {plugin_name} 配置中缺少blueprint_name字段")
            return False
            
        try:
            print(f"🔍 发现蓝图文件: {blueprint_name}.py")
            
            # 导入插件模块
            sys.path.insert(0, self.get_plugin_dir())
            try:
                module = importlib.import_module(f'{plugin_name}.{blueprint_name}')
                
                # 查找蓝图实例
                blueprint = None
                for attr_name in dir(module):
                    attr = getattr(module, attr_name)
                    if isinstance(attr, Blueprint):
                        blueprint = attr
                        break
                
                if blueprint:
                    # 注册蓝图
                    self.app.register_blueprint(blueprint)
                    print(f"✅ {plugin_name} 插件蓝图注册成功")
                    
                    # 保存模块引用
                    self.initialized_modules[f"{plugin_name}_blueprint"] = blueprint
                    self.initialized_modules[f"{plugin_name}_blueprint_module"] = module
                    
                    return True
                else:
                    print(f"❌ 插件 {plugin_name} 中未找到蓝图")
                    return False
                    
            except Exception as e:
                print(f"❌ 注册插件 {plugin_name} 失败: {e}")
                return False
                
            finally:
                if self.get_plugin_dir() in sys.path:
                    sys.path.remove(self.get_plugin_dir())
                    
        except Exception as e:
            print(f"❌ 处理插件 {plugin_name} 时出错: {e}")
            import traceback
            traceback.print_exc()
            return False
        
    def init_all_plugins(self) -> Dict[str, bool]:
        """初始化所有插件"""
        print("🎯 开始初始化所有插件...")
        
        # 先加载现有的插件信息
        self.load_existing_plugins_info()
        
        self.plugins = self.discover_plugins()
        
        if not self.plugins:
            print("⚠️ 没有发现任何插件")
            return {}
            
        results = {}
        total_success = 0
        
        for plugin_name, plugin_path in self.plugins.items():
            success = self.init_plugin(plugin_name, plugin_path)
            results[plugin_name] = success
            if success:
                total_success += 1
        
        # 保存插件信息到文件
        self.save_plugins_info()
                
        print(f"\n🎉 插件初始化完成: {total_success}/{len(self.plugins)} 个插件成功")
        return results
        
    def get_initialized_modules(self) -> Dict[str, Any]:
        """获取所有已初始化的插件模块"""
        return self.initialized_modules
        
    def get_plugin_module(self, module_name: str) -> Optional[Any]:
        """获取指定的插件模块"""
        return self.initialized_modules.get(module_name)
    
    def get_plugin_info(self, plugin_name: str) -> Optional[Dict]:
        """获取指定插件的配置信息"""
        return self.plugins_info.get(plugin_name)
    
    def get_all_plugins_info(self) -> Dict[str, Dict]:
        """获取所有插件的配置信息"""
        return self.plugins_info.copy()
    
    def is_plugin_enabled(self, plugin_name: str) -> bool:
        """
        检查插件是否启用
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            bool: 插件是否启用
        """
        if plugin_name not in self.plugins_info.items():
            return False
        return self.plugins_info[plugin_name].get('enabled', True)  # 默认启用
        
    def unload_plugin(self, plugin_name: str) -> bool:
        """
        卸载指定插件的所有模块
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            bool: 卸载是否成功
        """
        if plugin_name not in self.plugins:
            print(f"❌ 插件 {plugin_name} 不存在或未初始化")
            return False
            
        print(f"🔄 开始卸载插件: {plugin_name}")
        
        # 需要卸载的模块类型
        module_types = ['config','models', 'functions', 'helpers', 'utils', 'view']
        unloaded_count = 0
        
        for module_type in module_types:
            module_key = f"{plugin_name}_{module_type}"
            if module_key in self.initialized_modules:
                try:
                    # 如果模块有unload函数，则调用它
                    module = self.initialized_modules[module_key]
                    if hasattr(module, 'unload'):
                        if self.app:
                            module.unload(self.app)
                        else:
                            module.unload()
                        print(f"✅ {plugin_name} 插件 {module_type} 模块卸载成功")
                    else:
                        print(f"ℹ️ {plugin_name} 插件 {module_type} 模块没有unload函数")
                    
                    # 从已初始化模块中移除
                    del self.initialized_modules[module_key]
                    unloaded_count += 1
                    
                    # 如果是蓝图模块，还需要注销蓝图
                    if module_type == 'blueprint' and self.app:
                        try:
                            # 注销蓝图
                            if module.name in self.app.blueprints:
                                del self.app.blueprints[module.name]
                                print(f"✅ {plugin_name} 插件蓝图已注销: {module.name}")
                        except Exception as e:
                            print(f"❌ 注销 {plugin_name} 插件蓝图时发生错误: {e}")
                    
                except Exception as e:
                    print(f"❌ 卸载 {plugin_name} 插件 {module_type} 模块时发生错误: {e}")
                    import traceback
                    traceback.print_exc()
        
        # 从插件列表中移除
        if plugin_name in self.plugins:
            del self.plugins[plugin_name]
            print(f"📊 {plugin_name} 插件已从插件列表中移除")
        
        print(f"🎉 {plugin_name} 插件卸载完成: {unloaded_count} 个模块已卸载")
        return unloaded_count > 0
        
    def unload_all_plugins(self) -> Dict[str, bool]:
        """
        卸载所有插件
        
        Returns:
            Dict[str, bool]: 插件名称到卸载结果的映射
        """
        print("🔄 开始卸载所有插件...")
        
        if not self.plugins:
            print("ℹ️ 没有已初始化的插件需要卸载")
            return {}
            
        results = {}
        total_success = 0
        
        # 获取所有插件名称的副本，因为卸载过程中会修改self.plugins
        plugin_names = list(self.plugins.keys())
        
        for plugin_name in plugin_names:
            success = self.unload_plugin(plugin_name)
            results[plugin_name] = success
            if success:
                total_success += 1
                
        print(f"\n🎉 插件卸载完成: {total_success}/{len(plugin_names)} 个插件成功卸载")
        return results
        
    def reload_plugin(self, plugin_name: str) -> bool:
        """
        重新加载指定插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            bool: 重新加载是否成功
        """
        print(f"🔄 开始重新加载插件: {plugin_name}")
        
        # 先卸载插件
        unload_success = self.unload_plugin(plugin_name)
        
        # 重新发现插件
        self.plugins = self.discover_plugins()
        
        # 重新初始化插件
        if plugin_name in self.plugins:
            plugin_path = self.plugins[plugin_name]
            init_success = self.init_plugin(plugin_name, plugin_path)
            
            if init_success:
                print(f"✅ {plugin_name} 插件重新加载成功")
                return True
            else:
                print(f"❌ {plugin_name} 插件重新加载失败")
                return False
        else:
            print(f"❌ 重新发现插件时未找到 {plugin_name}")
            return False
            
    def get_plugin_status(self, plugin_name: str) -> Dict[str, Any]:
        """
        获取指定插件的状态信息
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            Dict[str, Any]: 插件状态信息
        """
        status = {
            'name': plugin_name,
            'exists': plugin_name in self.plugins,
            'path': self.plugins.get(plugin_name, ''),
            'enabled': self.is_plugin_enabled(plugin_name),
            'modules': {},
            'total_modules': 0,
            'loaded_modules': 0
        }
        
        if plugin_name in self.plugins:
            # 检查各种模块类型
            module_types = ['config', 'models','functions', 'helpers', 'utils', 'view']
            
            for module_type in module_types:
                module_key = f"{plugin_name}_{module_type}"
                module = self.initialized_modules.get(module_key)
                
                status['modules'][module_type] = {
                    'loaded': module is not None,
                    'has_init': hasattr(module, 'init') if module else False,
                    'has_unload': hasattr(module, 'unload') if module else False
                }
                
                if module:
                    status['loaded_modules'] += 1
                    
                status['total_modules'] += 1
                
        return status
        
    def get_all_plugins_status(self) -> Dict[str, Dict[str, Any]]:
        """
        获取所有插件的状态信息
        
        Returns:
            Dict[str, Dict[str, Any]]: 所有插件的状态信息
        """
        status = {}
        
        for plugin_name in self.plugins.keys():
            status[plugin_name] = self.get_plugin_status(plugin_name)
            
        return status

    def enable_plugin(self, plugin_name: str) -> bool:
        """
        启用指定插件（只更新启用状态）
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            bool: 启用是否成功
        """
        print(f"🚀 开始启用插件: {plugin_name}")
        
        # 检查插件是否存在
        if plugin_name not in self.plugins:
            print(f"❌ 插件 {plugin_name} 不存在，尝试重新发现...")
            # 重新发现插件
            self.plugins = self.discover_plugins()
            
            if plugin_name not in self.plugins:
                print(f"❌ 插件 {plugin_name} 不存在于插件目录中")
                return False
        
        # 检查插件信息是否存在
        if plugin_name not in self.plugins_info:
            print(f"❌ 插件 {plugin_name} 配置信息不存在")
            return False
        
        # 更新启用状态
        self.plugins_info[plugin_name]['enabled'] = True
        route_enable_plugin(plugin_name)
        print(f"✅ 插件 {plugin_name} 启用状态已更新")
        
        # 保存插件信息
        self.save_plugins_info()
        
        return True
            
    def disable_plugin(self, plugin_name: str) -> bool:
        """
        禁用指定插件（只更新启用状态）
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            bool: 禁用是否成功
        """
        print(f"🔄 开始禁用插件: {plugin_name}")
        
        # 检查插件是否存在
        if plugin_name not in self.plugins:
            print(f"❌ 插件 {plugin_name} 不存在")
            return False
        
        # 检查插件信息是否存在
        if plugin_name not in self.plugins_info:
            print(f"❌ 插件 {plugin_name} 配置信息不存在")
            return False
        
        # 更新启用状态
        self.plugins_info[plugin_name]['enabled'] = False
        route_disable_plugin(plugin_name)
        print(f"✅ 插件 {plugin_name} 禁用状态已更新")
        
        # 保存插件信息
        self.save_plugins_info()
        
        return True
        
    def get_active_plugins(self) -> List[str]:
        """
        获取当前激活的插件列表（基于启用状态）
        
        Returns:
            List[str]: 激活的插件名称列表
        """
        active_plugins = []
        
        for plugin_name, plugin_info in self.plugins_info.items():
            if plugin_info.get('enabled', True):  # 默认启用
                active_plugins.append(plugin_name)
                
        return active_plugins

    def upload_plugin_dynamic(zip_file, plugin_name: str = None) -> Dict:
        """动态上传插件"""
        manager = get_plugin_manager()
        return manager.upload_plugin(zip_file, plugin_name)

    def upload_plugin(self, zip_file, plugin_name: str = None) -> Dict:
        """上传并安装插件"""
        try:
            # 获取安全的文件名
            filename = secure_filename(zip_file.filename)
            if not filename.endswith('.zip'):
                return {'success': False, 'msg': '只支持ZIP格式的插件文件'}

            # 确定插件名称
            if plugin_name is None:
                plugin_name = filename[:-4]

            # 创建临时目录
            with tempfile.TemporaryDirectory() as temp_dir:
                # 保存ZIP文件
                zip_path = os.path.join(temp_dir, filename)
                zip_file.save(zip_path)

                # 解压ZIP文件
                plugin_dir = os.path.join(temp_dir, plugin_name)
                with zipfile.ZipFile(zip_path, 'r') as zip_ref:
                    zip_ref.extractall(plugin_dir)

                # 验证插件结构
                validation_result = self._validate_plugin(plugin_dir, plugin_name)
                if not validation_result['success']:
                    return validation_result

                # 安装插件
                return self._install_plugin(plugin_dir, plugin_name)

        except Exception as e:
            logger.error(f"上传插件失败: {e}")
            return {'success': False, 'msg': f'上传插件失败: {str(e)}'}

    def _validate_plugin(self, plugin_dir: str, plugin_name: str) -> Dict:
        """验证插件结构"""
        try:
            # 检查必需文件
            required_files = ['plugin.json', '__init__.py']
            for file in required_files:
                file_path = os.path.join(plugin_dir, file)
                if not os.path.exists(file_path):
                    return {'success': False, 'msg': f'插件缺少必需文件: {file}'}

            # 读取插件配置
            config_path = os.path.join(plugin_dir, 'plugin.json')
            with open(config_path, 'r', encoding='utf-8') as f:
                config = json.load(f)

            # 验证配置
            required_fields = ['name', 'version', 'description', 'author', 'modules']
            for field in required_fields:
                if field not in config:
                    return {'success': False, 'msg': f'插件配置缺少必需字段: {field}'}

            return {'success': True, 'config': config}

        except Exception as e:
            return {'success': False, 'msg': f'验证插件失败: {str(e)}'}

    def _install_plugin(self, plugin_dir: str, plugin_name: str) -> Dict:
        """安装插件"""
        try:
            # 读取插件配置
            config_path = os.path.join(plugin_dir, 'plugin.json')
            with open(config_path, 'r', encoding='utf-8') as f:
                config = json.load(f)

            # 检查插件是否已安装
            if plugin_name in self.plugins:
                return {'success': False, 'msg': f'插件 {plugin_name} 已经安装'}

            # 复制插件文件到插件目录
            target_dir = os.path.join(self.plugin_dir, plugin_name)
            if os.path.exists(target_dir):
                shutil.rmtree(target_dir)
            shutil.copytree(plugin_dir, target_dir)
            self.plugins[plugin_name] = target_dir
            # 保存插件信息

            self.plugins_info[plugin_name] = {
                'name': config.get('name'),
                'version': config.get('version'),
                'description': config.get('description'),
                'author': config.get('author'),
                'blueprint_name':config.get('blueprint_name'),
                'url_prefix':config.get('url_prefix'),
                'modules': config.get('modules'),
                'installed_at': str(datetime.datetime.now())
            }
            self._save_plugins_info()
            return {
                'success': True,
                'msg': f'插件 {plugin_name} 安装成功',
                'plugin': self.plugins[plugin_name]
            }
        except Exception as e:
            logger.error(f"安装插件失败: {e}")
            return {'success': False, 'msg': f'安装插件失败: {str(e)}'}
    def _save_plugins_info(self):
        """保存插件信息（兼容旧版本）"""
        self.save_plugins_info()

# 全局插件管理器实例
_plugin_manager = None


def get_plugin_manager(app: Flask = None) -> PluginManager:
    """获取插件管理器实例"""
    global _plugin_manager
    
    if app is None:
        from flask import current_app
        app = current_app
    
    if _plugin_manager is None or _plugin_manager.app != app:
        _plugin_manager = PluginManager(app)
    
    return _plugin_manager

def upload_plugin_dynamic(zip_file, plugin_name: str = None) -> Dict:
    """动态上传插件"""
    manager = get_plugin_manager()
    return manager.upload_plugin(zip_file, plugin_name)
def enable_plugin(plugin_name: str) -> bool:
    manager = get_plugin_manager()
    manager.enable_plugin(plugin_name)

def disable_plugin(plugin_name: str) -> bool:
    manager = get_plugin_manager()
    manager.disable_plugin(plugin_name)

def init_plugin_manager(app: Flask) -> PluginManager:
    """初始化插件管理器"""
    manager = get_plugin_manager(app)
    manager.init_all_plugins()
    return manager 